<?php

/**
 * Admin form.
 *
 * @package    docplus.co.za
 * @subpackage form
 * @author     Fox Matuku
 * @version    SVN: $Id: sfDoctrineFormTemplate.php 23810 2009-11-12 11:07:44Z Kris.Wallsmith $
 */
class AdminForm extends BaseAdminForm {
	private $requiredFields = array('email');

	public function configure() {
		unset(
			$this['created_at'], $this['updated_at']
		);

		// grab the gender generated options
		$genderOptions = $this->widgetSchema['gender']->getOptions("choices");

		$this->widgetSchema['user_id'] = new sfWidgetFormInputHidden();
		$this->widgetSchema['first_name'] = new sfWidgetFormInputText(array(), array("autocomplete" => "off"));
		$this->widgetSchema['last_name'] = new sfWidgetFormInputText(array(), array("autocomplete" => "off"));
		$this->widgetSchema['email'] = new sfWidgetFormInputText(array(), array("autocomplete" => "off"));
		$this->widgetSchema['password'] = new sfWidgetFormInputPassword(array(), array("autocomplete" => "off"));
		$this->widgetSchema['password_confirm'] = clone $this->widgetSchema['password'];
		$this->widgetSchema['password_confirm']->setLabel("Confirm password");
		$this->widgetSchema['gender']->setOption("choices", array_merge(array("" => "Please select a gender"), $genderOptions["choices"]));
		$this->widgetSchema['gender']->setAttribute("class", "select-box-small");
		$this->widgetSchema['language_id']->setOption("add_empty", "Please select a language");
		$this->widgetSchema["language_id"]->setAttribute("class", "select-box-small");
		$this->widgetSchema['is_active'] = new sfWidgetFormInputCheckbox();
		$this->widgetSchema['is_super_admin'] = new sfWidgetFormInputCheckbox();
		//$this->widgetSchema['groups_list'] = new sfWidgetFormDoctrineChoice(array('multiple' => true, 'model' => 'GfGroup'));
		//$this->widgetSchema['permissions_list'] = new sfWidgetFormDoctrineChoice(array('multiple' => true, 'model' => 'GfPermission'));
		///$this->widgetSchema['groups_list']->setLabel('Groups');
		//$this->widgetSchema['permissions_list']->setLabel('Permissions');

		$this->validatorSchema['user_id'] = new sfValidatorString(array('required' => false));
		$this->validatorSchema['language_id'] = new sfValidatorString(array('max_length' => 255, 'required' => true), array('required' => 'The *language* field is required.'));
		$this->validatorSchema['gender'] = new sfValidatorString(array('max_length' => 255, 'required' => true), array('required' => 'The *gender* field is required.'));
		$this->validatorSchema['first_name'] = new sfValidatorString(array('max_length' => 255, 'required' => true), array('required' => 'The *first name* field is required.'));
		$this->validatorSchema['last_name'] = new sfValidatorString(array('max_length' => 255, 'required' => true), array('required' => 'The *last name* field is required.'));
		$this->validatorSchema['email'] = new sfValidatorEmail(array("required" => true), array("invalid" => "The *email* field is invalid.", "required" => "The *email* field is required email."));
		$this->validatorSchema['password'] = new sfValidatorString(array('required' => true, 'max_length' => 128, 'required' => $this->getObject()->isNew()), array('required' => 'The *password* field is required.'));
		$this->validatorSchema['password_confirm'] = clone $this->validatorSchema['password'];
		$this->validatorSchema['password_confirm']->setMessage('required', 'The *confirm password* field is required.');
		$this->validatorSchema['is_active'] = new sfValidatorString(array('required' => false));
		$this->validatorSchema['is_super_admin'] = new sfValidatorString(array('required' => false));
		//$this->validatorSchema['groups_list'] = new sfValidatorDoctrineChoice(array('multiple' => true, 'model' => 'GfGroup', 'required' => false));
		//$this->validatorSchema['permissions_list'] = new sfValidatorDoctrineChoice(array('multiple' => true, 'model' => 'GfPermission', 'required' => false));

		$this->validatorSchema->setPostValidator(new sfValidatorCallback(array('callback' => array($this, '_emailAlreadyExistsValidator'))));
		$this->mergePostValidator(new sfValidatorSchemaCompare('password', sfValidatorSchemaCompare::EQUAL, 'password_confirm', array(), array('invalid' => 'The *two passwords* must be the same.')));

		$this->setDefaults(array(
			'user_id' => $this->getObject()->getUserId(),
			'first_name' => $this->getObject()->getUser()->getFirstName(),
			'last_name' => $this->getObject()->getUser()->getLastName(),
			'email' => $this->getObject()->getUser()->getEmail(),
			'gender' => $this->getObject()->getGender(),
			'language_id' => $this->getObject()->getLanguageId(),
			'is_active' => $this->getObject()->getUser()->getIsActive(),
			'is_super_admin' => $this->getObject()->getUser()->getIsSuperAdmin()
		));
	}

	public function _emailAlreadyExistsValidator($validator, $values, $arguments) {
		foreach ($this->requiredFields as $field) {
			try {
				$this->validatorSchema[$field]->clean($values[$field]);
			}
			catch (sfValidatorErrorSchema $e) {
				return $values;
			}
			catch (sfValidatorError $e) {
				return $values;
			}
		}

		// try to fetch the registered user
		$gfUser = GfUserTable::getInstance()->findOneByEmail($values['email']);

		// check for the existence of this email
		if (is_object($gfUser) && $gfUser->getId() != $values["user_id"]) {
			$this->validatorSchema['email']->setMessage('invalid', 'This email already vcvxexists.');
		}
		else {
			return $values;
		}

		// since we've reached here seems the supplied email exists already
		throw new sfValidatorErrorSchema($this->validatorSchema['email'], array('email' => new sfValidatorError($this->validatorSchema['email'], 'invalid')));
		return $values;
	}

	/**
	 * Override the save method to save the merged user form.
	 */
	public function save($con = null) {
		$this->updateUser();
		return parent::save($con);
	}

	/**
	 * Updates the user merged form
	 */
	protected function updateUser() {
		if (!is_null($gfUser = $this->getUser())) {
			if (!$gfUser->getId()) {
				$gfUser->setAlgorithm('md5');
				$gfUser->setType("Admin");
			}
			$gfUser->setFirstName($this->getValue("first_name"));
			$gfUser->setLastName($this->getValue("last_name"));
			$gfUser->setEmail($this->getValue("email"));
			$gfUser->setIsActive($this->getValue("is_active") ? true : false);
			$gfUser->setIsSuperAdmin($this->getValue("is_super_admin") ? true : false);

			$password = $this->getValue("password");

			// make sure we don't save empty passwords
			if (!empty($password)) {
				$gfUser->setPassword($password);
			}

			$gfUser->save();

			unset($this->values['first_name'], $this->values['last_name'], $this->values['email'], $this->values['password'], $this->values['is_active'], $this->values['is_super_admin']);

			// set the user id
			$this->values['user_id'] = $gfUser->get('id');
		}
	}

	/**
	 * Returns the user object. If it does not exist return a new instance.
	 *
	 * @return sfGuardUser
	 */
	protected function getUser() {
		if (!$this->getObject()->getUser()) {
			return new GfUser();
		}

		return $this->getObject()->getUser();
	}

	public function updateDefaultsFromObject() {

//		if (isset($this->widgetSchema['groups_list'])) {
//			$this->setDefault('groups_list', $this->object->User->Groups->getPrimaryKeys());
//		}
//
//		if (isset($this->widgetSchema['permissions_list'])) {
//			$this->setDefault('permissions_list', $this->object->User->Permissions->getPrimaryKeys());
//		}
	}

	protected function doSave($con = null) {
		$this->saveGroupsList($con);
		$this->savePermissionsList($con);

		//$this->object->getUser()->save();
	}

	public function saveGroupsList($con = null) {
		if (!$this->isValid()) {
			throw $this->getErrorSchema();
		}

		if (!isset($this->widgetSchema['groups_list'])) {
			// somebody has unset this widget
			return;
		}

		if (null === $con) {
			$con = $this->getConnection();
		}

		$existing = $this->object->getUser()->Groups->getPrimaryKeys();
		$values = $this->getValue('groups_list');
		if (!is_array($values)) {
			$values = array();
		}

		$unlink = array_diff($existing, $values);
		if (count($unlink)) {
			$this->object->getUser()->unlink('Groups', array_values($unlink));
		}

		$link = array_diff($values, $existing);
		if (count($link)) {

			gfToolkit::debug(array_values($link));

			$this->object->getUser()->link('Groups', array_values($link));
		}

		gfToolkit::debug(array_values($link));
	}

	public function savePermissionsList($con = null) {
		if (!$this->isValid()) {
			throw $this->getErrorSchema();
		}

		if (!isset($this->widgetSchema['permissions_list'])) {
			// somebody has unset this widget
			return;
		}

		if (null === $con) {
			$con = $this->getConnection();
		}

		$existing = $this->object->getUser()->Permissions->getPrimaryKeys();
		$values = $this->getValue('permissions_list');
		if (!is_array($values)) {
			$values = array();
		}

		$unlink = array_diff($existing, $values);
		if (count($unlink)) {
			$this->object->getUser()->unlink('Permissions', array_values($unlink));
		}

		$link = array_diff($values, $existing);
		if (count($link)) {
			$this->object->getUser()->link('Permissions', array_values($link));
		}

		gfToolkit::debug(array_values($link));
	}

}